package com.demo.fullink.service.impl;

import com.demo.fullink.rabbitmq.MQProducer;
import com.demo.fullink.service.AccountService;
import com.demo.fullink.service.OrderService;
import com.demo.fullink.service.StorageOrderService;
import com.demo.fullink.service.StorageProductService;
import com.demo.fulllink.common.emum.ResponseErrorEnum;
import com.demo.fulllink.common.utils.CommonUtils;
import com.demo.fulllink.common.utils.IdWorker;
import com.demo.fulllink.module.po.OrderPO;
import com.demo.fulllink.module.vo.OrderVO;
import com.demo.fulllink.module.vo.ResponseVO;
import com.demo.wormhole.core.context.WormholeContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

@Service
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private IdWorker idWorker;
    
    @Autowired
    private AccountService accountService;
    
    @Autowired
    private StorageOrderService storageOrderService;
    
    @Autowired
    private StorageProductService storageProductService;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Autowired
    private MQProducer mqProducer;
    
    /**
     * 下单
     *
     * @param orderVO
     * @return
     */
    @Override
    public ResponseVO placeOrder(OrderVO orderVO) {
        //Redis预扣库存
        boolean deductionStatus = predDeductionStock(orderVO.getProductId());
        //预扣库存成功才下一步
        if (deductionStatus) {
            //处理订单业务
            return handelOrder(orderVO);
        }
        return ResponseErrorEnum.STOCK_ERROR.toResponseVO();
    }
    
    private ResponseVO handelOrder(OrderVO orderVO) {
        //校验账户是否存在
        ResponseVO responseVO = accountService.checkAccount(orderVO.getAccountId());
        //账户状态正常才下一步操作
        if (null != responseVO && responseVO.isSuccess()) {
            //生成订单号
            String orderId = String.valueOf(idWorker.nextId());
            //订单放缓存
            redisTemplate.opsForValue().set(CommonUtils.getOrderIdempotentKey(orderId), orderId, 30, TimeUnit.MINUTES);
            //订单对象赋值
            orderVO.setId(orderId);
            orderVO.setStatus(0);
            
            //设置链路Token
            orderVO.setToken(WormholeContextHolder.getProperty(null));
            //预先插入数据库
            storageOrderService.insert(orderVO);
            //发送消息通知
            mqProducer.sendOrder(orderVO);
            responseVO.setData(orderVO);
            responseVO.setMessage("订单提交成功，订单号:" + orderId);
            
        }
        return responseVO;
    }
    
    @Override
    public ResponseVO findOrder(Serializable orderId) {
        OrderPO orderPO = storageOrderService.findByID(orderId);
        if (null == orderPO) {
            return ResponseErrorEnum.ORDER_ERROR.toResponseVO();
        }
        ResponseVO responseVO = ResponseVO.success(orderPO);
        if (responseVO.isSuccess()) {
            if (orderPO.getStatus() == 2) {
                responseVO.setMessage("订单交易成功...");
            } else {
                responseVO.setMessage("订单正在处理中...");
            }
        }
        
        return responseVO;
    }
    
    @Override
    public String notifyOrder() {
        return null;
    }
    
    /**
     * 预扣库存
     *
     * @param productId
     */
    private boolean predDeductionStock(Serializable productId) {
        String productStockKey = CommonUtils.getProductStockKey(productId);
        Long productStock = redisTemplate.opsForValue().decrement(productStockKey);
        return productStock.longValue() >= 0 ? true : false;
    }
}
